package com.taobao.ui.widget;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Widget;

import com.swtdesigner.SWTResourceManager;
import com.taobao.pojo.Config;
import com.taobao.pojo.TBImage;
import com.taobao.pojo.Task;
import com.taobao.tools.Binding;
import com.taobao.tools.GIF;

public abstract class CommonWidget extends Composite {

	public static String ID = "";

	public CommonWidget(Composite parent, int style) {
		super(parent, style);
		Config.uiContext.put(getID(), this);
	}

	public <T> T getThis(Class<T> t) {
		return t.cast(this);
	}

	public abstract String getID();

	public <T> T getPojo(Class<T> pojoClass) {
		try {
			Map<Widget, String> groupMap = Binding.getBindingGroup();
			Map<Widget, Class<?>> pojoMap = Binding.getBindingPojo();
			Map<Widget, String> pojoFieldMap = Binding.getBindingPojoField();
			Object pojo = pojoClass.newInstance();
			for (Widget widget : pojoMap.keySet()) {
				if (!widget.isDisposed()) {
					Class<?> clazz = pojoMap.get(widget);
					if (pojoClass.getName().equals(clazz.getName())) {
						String groupType = groupMap.get(widget);
						Method method = getClass().getMethod("get" + groupType.substring(groupType.indexOf("_") + 1) + "Value", Widget.class);
						Object value = method.invoke(this, widget);

						Field field = pojoClass.getDeclaredField(pojoFieldMap.get(widget));
						field.setAccessible(true);
						field.set(pojo, value);
					}
				}
			}
			return pojoClass.cast(pojo);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	public void fillWidget(Object pojo) {
		try {
			Map<CommonWidget, List<Widget>> widgetMap = Binding.getBindingWidgets();
			Map<Widget, String> groupMap = Binding.getBindingGroup();
			Map<Widget, Class<?>> pojoMap = Binding.getBindingPojo();
			Map<Widget, String> pojoFieldMap = Binding.getBindingPojoField();

			List<Widget> widgets = widgetMap.get(this);
			for (Widget widget : widgets) {
				if (!widget.isDisposed()) {
					Class<?> clazz = pojoMap.get(widget);
					if (pojo.getClass().getName().equals(clazz.getName())) {
						String souceType = groupMap.get(widget);
						String fieldName = pojoFieldMap.get(widget);
						Method method = getClass().getMethod("set" + souceType.substring(souceType.indexOf("_") + 1) + "Value", new Class[] { Widget.class, Object.class });
						if (method != null) {
							Field field = pojo.getClass().getDeclaredField(fieldName);
							field.setAccessible(true);
							Object value = field.get(pojo);
							if (value != null) {
								method.invoke(this, new Object[] { widget, value });
							}
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void setTextValue(Widget widget, Object value) {
		Text text = (Text) widget;
		text.setText((String) value);
	}

	@SuppressWarnings("unchecked")
	public void setLabelForButtonValue(Widget widget, Object value) {
		Label label = (Label) widget;
		List<Task> tasks = (List<Task>) value;
		if (tasks != null) {
		    String text = label.getText();
		    String before = text.substring(0, text.indexOf("(") + 1);
		    String after = text.substring(text.indexOf(")"));
		    label.setText(before + tasks.size() + after);
		    if(tasks.size() > 0){
		        label.setForeground(SWTResourceManager.getColor(SWT.COLOR_RED));
		    } else {
		        label.setForeground(SWTResourceManager.getColor(SWT.COLOR_BLACK));
		    }
		}
		label.setData(tasks);
	}

	public void setCheckValue(Widget widget, Object value) {
		Button button = (Button) widget;
		button.setSelection(Boolean.valueOf((String) value));
	}

	public void setComboValue(Widget widget, Object value) {
		Combo combo = (Combo) widget;
		combo.setText((String) value);
	}

	public void setLevelImageValue(Widget widget, Object value) {
		TBImage tbImage = (TBImage) value;
		if (widget.getData() == null || (widget.getData() != null && !((TBImage) widget.getData()).getImageUrl().equals(tbImage.getImageUrl()))) {
			if (widget instanceof Text) {
				new GIF().gif((Text) widget, getShell(), tbImage.getLocalUrl());
			} else if (widget instanceof Label) {
				new GIF().gif((Label) widget, getShell(), tbImage.getLocalUrl());
			}
			widget.setData(tbImage);
		}
	}

	public void setListSizeValue(Widget widget, Object value) {
		List<?> list = (List<?>) value;
		if (widget instanceof Text) {
			((Text) widget).setText(list.size() + "");
		} else if (widget instanceof Label) {
			((Label) widget).setText(list.size() + "");
		}
		widget.setData(list);
	}

	public void setListValue(Widget widget, Object value) {
		List<?> list = (List<?>) value;
		widget.setData(list);

		Table table = (Table) widget;
		table.removeAll();
		TableColumn[] cols = table.getColumns();

		for (Object object : list) {
			Map<String, Object> map = fieldToMap(object);
			String[] itemData = new String[cols.length];
			int i = 0;
			for (TableColumn tableColumn : cols) {
				String tool = tableColumn.getToolTipText();
				if (tool != null) {
					itemData[i] = map.get(tool) == null ? "" : map.get(tool).toString();
				}
				i++;
			}
			TableItem item = new TableItem(table, SWT.NONE);
			item.setText(itemData);
			item.setData(object);
			if (map.get("bgColor") != null) {
				item.setBackground((Color) map.get("bgColor"));
			}
		}
	}

	public String getTextValue(Widget widget) {
		Text text = (Text) widget;
		return text.getText();
	}

	public List<?> getLabelForButtonValue(Widget widget) {
		return (List<?>) widget.getData();
	}

	public String getCheckValue(Widget widget) {
		Button button = (Button) widget;
		return button.getSelection() ? "true" : "false";
	}

	public String getComboValue(Widget widget) {
		Combo combo = (Combo) widget;
		return combo.getText();
	}

	public TBImage getLevelImageValue(Widget widget) {
		return (TBImage) widget.getData();
	}

	public List<?> getListSizeValue(Widget widget) {
		return (List<?>) widget.getData();
	}

	public List<?> getListValue(Widget widget) {
		return (List<?>) widget.getData();
	}

	private Map<String, Object> fieldToMap(Object value) {
		Map<String, Object> map = new HashMap<String, Object>();
		Field[] fields = value.getClass().getDeclaredFields();
		for (Field field : fields) {
			field.setAccessible(true);
			try {
				map.put(field.getName(), field.get(value));
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
		}
		return map;
	}
}
